<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>股票估值数据抓取系统</title>
    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- Chart.js -->
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: #f8f9fa;
        }
        .card {
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            margin-bottom: 20px;
        }
        .card-header {
            background-color: #0d6efd;
            color: white;
            border-radius: 8px 8px 0 0;
        }
        .form-control:focus {
            border-color: #0d6efd;
            box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25);
        }
        .btn-primary {
            background-color: #0d6efd;
            border-color: #0d6efd;
        }
        .btn-primary:hover {
            background-color: #0b5ed7;
            border-color: #0a58ca;
        }
        .alert {
            margin-top: 20px;
        }
        .table {
            border-radius: 8px;
            overflow: hidden;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .chart-container {
            position: relative;
            height: 400px;
            margin-top: 20px;
        }
        .tab-content {
            padding: 20px;
            background-color: white;
            border-radius: 0 0 8px 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .nav-tabs {
            margin-bottom: 0;
        }
        .nav-tabs .nav-link.active {
            background-color: white;
            border-bottom-color: white;
            color: #0d6efd;
            font-weight: bold;
        }
        .loading-spinner {
            display: none;
            text-align: center;
            padding: 20px;
        }
    </style>
</head>
<body>
    <div class="container mt-5">
        <h1 class="text-center mb-5">股票估值数据抓取系统</h1>
        
        <!-- 标签页导航 -->
        <ul class="nav nav-tabs" id="mainTabs" role="tablist">
            <li class="nav-item" role="presentation">
                <button class="nav-link active" id="fetch-tab" data-bs-toggle="tab" data-bs-target="#fetch" type="button" role="tab" aria-controls="fetch" aria-selected="true">数据抓取</button>
            </li>
            <li class="nav-item" role="presentation">
                <button class="nav-link" id="query-tab" data-bs-toggle="tab" data-bs-target="#query" type="button" role="tab" aria-controls="query" aria-selected="false">数据查询</button>
            </li>
            <li class="nav-item" role="presentation">
                <button class="nav-link" id="visualize-tab" data-bs-toggle="tab" data-bs-target="#visualize" type="button" role="tab" aria-controls="visualize" aria-selected="false">数据可视化</button>
            </li>
        </ul>
        
        <!-- 标签页内容 -->
        <div class="tab-content" id="mainTabsContent">
            <!-- 数据抓取标签页 -->
            <div class="tab-pane fade show active" id="fetch" role="tabpanel" aria-labelledby="fetch-tab">
                <div class="row">
                    <!-- 单只股票抓取 -->
                    <div class="col-md-6">
                        <div class="card">
                            <div class="card-header">
                                <h5 class="mb-0">单只股票数据抓取</h5>
                            </div>
                            <div class="card-body">
                                <div class="mb-3">
                                    <label for="securityCode" class="form-label">证券代码</label>
                                    <input type="text" class="form-control" id="securityCode" placeholder="请输入证券代码，如：000001">
                                </div>
                                <button id="fetchSingleBtn" class="btn btn-primary w-100">抓取数据</button>
                            </div>
                        </div>
                    </div>
                    
                    <!-- 批量股票抓取 -->
                    <div class="col-md-6">
                        <div class="card">
                            <div class="card-header">
                                <h5 class="mb-0">批量股票数据抓取</h5>
                            </div>
                            <div class="card-body">
                                <div class="mb-3">
                                    <label for="batchSecurityCodes" class="form-label">证券代码（每行一个）</label>
                                    <textarea class="form-control" id="batchSecurityCodes" rows="4" placeholder="请输入证券代码，每行一个"></textarea>
                                </div>
                                <button id="fetchBatchBtn" class="btn btn-primary w-100">批量抓取</button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- 数据查询标签页 -->
            <div class="tab-pane fade" id="query" role="tabpanel" aria-labelledby="query-tab">
                <div class="card">
                    <div class="card-body">
                        <div class="row mb-4">
                            <div class="col-md-4">
                                <div class="mb-3">
                                    <label for="querySecurityCode" class="form-label">证券代码</label>
                                    <input type="text" class="form-control" id="querySecurityCode" placeholder="请输入证券代码">
                                </div>
                            </div>
                            <div class="col-md-3">
                                <div class="mb-3">
                                    <label for="startDate" class="form-label">开始日期</label>
                                    <input type="date" class="form-control" id="startDate">
                                </div>
                            </div>
                            <div class="col-md-3">
                                <div class="mb-3">
                                    <label for="endDate" class="form-label">结束日期</label>
                                    <input type="date" class="form-control" id="endDate">
                                </div>
                            </div>
                            <div class="col-md-2">
                                <div class="mb-3">
                                    <label class="form-label" style="visibility: hidden;">查询按钮</label>
                                    <button id="queryBtn" class="btn btn-primary w-100">查询</button>
                                </div>
                            </div>
                        </div>
                        
                        <div class="loading-spinner" id="querySpinner">
                            <div class="spinner-border" role="status">
                                <span class="visually-hidden">加载中...</span>
                            </div>
                            <p class="mt-2">正在查询数据，请稍候...</p>
                        </div>
                        
                        <div id="queryResult" class="mt-4">
                            <!-- 查询结果将在这里显示 -->
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- 数据可视化标签页 -->
            <div class="tab-pane fade" id="visualize" role="tabpanel" aria-labelledby="visualize-tab">
                <div class="card">
                    <div class="card-body">
                        <div class="row mb-4">
                            <div class="col-md-4">
                                <div class="mb-3">
                                    <label for="visualSecurityCode" class="form-label">证券代码</label>
                                    <input type="text" class="form-control" id="visualSecurityCode" placeholder="请输入证券代码">
                                </div>
                            </div>
                            <div class="col-md-3">
                                <div class="mb-3">
                                    <label for="visualDataCount" class="form-label">数据条数</label>
                                    <select class="form-select" id="visualDataCount">
                                        <option value="10">最近10条</option>
                                        <option value="20">最近20条</option>
                                        <option value="30">最近30条</option>
                                        <option value="50">最近50条</option>
                                    </select>
                                </div>
                            </div>
                            <div class="col-md-2">
                                <div class="mb-3">
                                    <label class="form-label" style="visibility: hidden;">生成图表</label>
                                    <button id="generateChartBtn" class="btn btn-primary w-100">生成图表</button>
                                </div>
                            </div>
                        </div>
                        
                        <div class="loading-spinner" id="chartSpinner">
                            <div class="spinner-border" role="status">
                                <span class="visually-hidden">加载中...</span>
                            </div>
                            <p class="mt-2">正在生成图表，请稍候...</p>
                        </div>
                        
                        <div class="chart-container mt-4">
                            <canvas id="peChart"></canvas>
                        </div>
                        
                        <div class="chart-container mt-4">
                            <canvas id="roeChart"></canvas>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <!-- 操作结果提示 -->
        <div id="alertContainer" class="mt-4">
            <!-- 提示信息将在这里显示 -->
        </div>
    </div>
    
    <!-- Bootstrap Bundle with Popper -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    
    <script>
        // 显示提示信息
        function showAlert(message, type = 'success') {
            const alertContainer = document.getElementById('alertContainer');
            const alert = document.createElement('div');
            alert.className = `alert alert-${type} alert-dismissible fade show`;
            alert.role = 'alert';
            alert.innerHTML = `
                ${message}
                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
            `;
            alertContainer.innerHTML = '';
            alertContainer.appendChild(alert);
            
            // 3秒后自动关闭提示
            setTimeout(() => {
                const alertInstance = bootstrap.Alert.getInstance(alert);
                if (alertInstance) {
                    alertInstance.close();
                }
            }, 5000);
        }
        
        // 显示加载状态
        function showLoading(elementId) {
            const spinner = document.getElementById(elementId);
            if (spinner) {
                spinner.style.display = 'block';
            }
        }
        
        // 隐藏加载状态
        function hideLoading(elementId) {
            const spinner = document.getElementById(elementId);
            if (spinner) {
                spinner.style.display = 'none';
            }
        }
        
        // 单只股票数据抓取
        document.getElementById('fetchSingleBtn').addEventListener('click', function() {
            const securityCode = document.getElementById('securityCode').value.trim();
            if (!securityCode) {
                showAlert('请输入证券代码', 'warning');
                return;
            }
            
            showLoading('alertContainer');
            
            fetch(`/api/stockpe/fetch/${securityCode}`)
                .then(response => response.text())
                .then(data => {
                    hideLoading('alertContainer');
                    if (data.includes('成功') || data.includes('提示')) {
                        showAlert(data, 'success');
                    } else {
                        showAlert(data, 'danger');
                    }
                })
                .catch(error => {
                    hideLoading('alertContainer');
                    showAlert('抓取失败：' + error.message, 'danger');
                    console.error('Fetch error:', error);
                });
        });
        
        // 批量股票数据抓取
        document.getElementById('fetchBatchBtn').addEventListener('click', function() {
            const textarea = document.getElementById('batchSecurityCodes');
            const codesText = textarea.value.trim();
            
            if (!codesText) {
                showAlert('请输入证券代码', 'warning');
                return;
            }
            
            const securityCodes = codesText.split('\n').map(code => code.trim()).filter(code => code);
            
            if (securityCodes.length === 0) {
                showAlert('请输入有效的证券代码', 'warning');
                return;
            }
            
            if (securityCodes.length > 20) {
                showAlert('一次最多批量抓取20只股票', 'warning');
                return;
            }
            
            showLoading('alertContainer');
            
            fetch('/api/stockpe/fetch/batch', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(securityCodes)
            })
            .then(response => response.text())
            .then(data => {
                hideLoading('alertContainer');
                showAlert(data.replace(/\n/g, '<br>'), 'success');
            })
            .catch(error => {
                hideLoading('alertContainer');
                showAlert('批量抓取失败：' + error.message, 'danger');
                console.error('Batch fetch error:', error);
            });
        });
        
        // 查询股票估值数据
        document.getElementById('queryBtn').addEventListener('click', function() {
            const securityCode = document.getElementById('querySecurityCode').value.trim();
            const startDate = document.getElementById('startDate').value;
            const endDate = document.getElementById('endDate').value;
            
            if (!securityCode) {
                showAlert('请输入证券代码', 'warning');
                return;
            }
            
            let queryUrl = `/api/stockpe/query?securityCode=${securityCode}`;
            if (startDate) {
                queryUrl += `&startDate=${startDate}`;
            }
            if (endDate) {
                queryUrl += `&endDate=${endDate}`;
            }
            
            showLoading('querySpinner');
            document.getElementById('queryResult').innerHTML = '';
            
            fetch(queryUrl)
                .then(response => {
                    if (!response.ok) {
                        throw new Error('查询失败');
                    }
                    return response.json();
                })
                .then(data => {
                    hideLoading('querySpinner');
                    displayQueryResult(data);
                })
                .catch(error => {
                    hideLoading('querySpinner');
                    showAlert('查询失败：' + error.message, 'danger');
                    console.error('Query error:', error);
                });
        });
        
        // 显示查询结果
        function displayQueryResult(data) {
            const resultContainer = document.getElementById('queryResult');
            
            if (!data || data.length === 0) {
                resultContainer.innerHTML = '<div class="alert alert-info">未找到数据</div>';
                return;
            }
            
            let html = `
                <table class="table table-striped table-hover">
                    <thead class="table-dark">
                        <tr>
                            <th>证券代码</th>
                            <th>证券名称</th>
                            <th>交易日期</th>
                            <th>市盈率TTM</th>
                            <th>每股收益</th>
                            <th>每股未分配利润</th>
                            <th>ROE_TTM</th>
                            <th>ROE_TTM环比</th>
                            <th>ROE_TTM同比</th>
                            <th>更新次数</th>
                        </tr>
                    </thead>
                    <tbody>
            `;
            
            data.forEach(item => {
                html += `
                    <tr>
                        <td>${item.securityCode}</td>
                        <td>${item.securityName || '-'}</td>
                        <td>${formatDate(item.tradeDate)}</td>
                        <td>${formatNumber(item.peTTM)}</td>
                        <td>${formatNumber(item.dilutedEps)}</td>
                        <td>${formatNumber(item.undistributedProfitPerShare)}</td>
                        <td>${formatNumber(item.roeTTM)}%</td>
                        <td>${formatNumber(item.roeTTMQuarterly)}</td>
                        <td>${formatNumber(item.roeTTMYearly)}</td>
                        <td>${item.updateCount || 0}</td>
                    </tr>
                `;
            });
            
            html += '</tbody></table>';
            resultContainer.innerHTML = html;
        }
        
        // 生成图表
        document.getElementById('generateChartBtn').addEventListener('click', function() {
            const securityCode = document.getElementById('visualSecurityCode').value.trim();
            const dataCount = document.getElementById('visualDataCount').value;
            
            if (!securityCode) {
                showAlert('请输入证券代码', 'warning');
                return;
            }
            
            showLoading('chartSpinner');
            
            fetch(`/api/stockpe/query?securityCode=${securityCode}`)
                .then(response => {
                    if (!response.ok) {
                        throw new Error('获取数据失败');
                    }
                    return response.json();
                })
                .then(data => {
                    hideLoading('chartSpinner');
                    if (data && data.length > 0) {
                        // 只使用最近的N条数据，并按日期升序排列
                        const sortedData = data.slice(0, parseInt(dataCount)).reverse();
                        createPeChart(sortedData);
                        createRoeChart(sortedData);
                    } else {
                        showAlert('未找到数据，无法生成图表', 'info');
                    }
                })
                .catch(error => {
                    hideLoading('chartSpinner');
                    showAlert('生成图表失败：' + error.message, 'danger');
                    console.error('Chart error:', error);
                });
        });
        
        // 创建PE_TTM图表
        function createPeChart(data) {
            const ctx = document.getElementById('peChart').getContext('2d');
            const dates = data.map(item => formatDate(item.tradeDate));
            const peValues = data.map(item => item.peTTM || 0);
            
            // 销毁现有图表
            if (window.peChartInstance) {
                window.peChartInstance.destroy();
            }
            
            window.peChartInstance = new Chart(ctx, {
                type: 'line',
                data: {
                    labels: dates,
                    datasets: [{
                        label: '市盈率TTM',
                        data: peValues,
                        borderColor: 'rgb(75, 192, 192)',
                        tension: 0.1,
                        fill: false
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        title: {
                            display: true,
                            text: '市盈率TTM趋势图',
                            font: {
                                size: 16
                            }
                        },
                        legend: {
                            position: 'bottom'
                        }
                    },
                    scales: {
                        y: {
                            beginAtZero: false,
                            title: {
                                display: true,
                                text: '市盈率'
                            }
                        },
                        x: {
                            title: {
                                display: true,
                                text: '日期'
                            }
                        }
                    }
                }
            });
        }
        
        // 创建ROE图表
        function createRoeChart(data) {
            const ctx = document.getElementById('roeChart').getContext('2d');
            const dates = data.map(item => formatDate(item.tradeDate));
            const roeValues = data.map(item => item.roeTTM || 0);
            
            // 销毁现有图表
            if (window.roeChartInstance) {
                window.roeChartInstance.destroy();
            }
            
            window.roeChartInstance = new Chart(ctx, {
                type: 'line',
                data: {
                    labels: dates,
                    datasets: [{
                        label: 'ROE_TTM(%)',
                        data: roeValues,
                        borderColor: 'rgb(255, 99, 132)',
                        tension: 0.1,
                        fill: false
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        title: {
                            display: true,
                            text: 'ROE_TTM趋势图',
                            font: {
                                size: 16
                            }
                        },
                        legend: {
                            position: 'bottom'
                        }
                    },
                    scales: {
                        y: {
                            beginAtZero: false,
                            title: {
                                display: true,
                                text: 'ROE (%)'
                            }
                        },
                        x: {
                            title: {
                                display: true,
                                text: '日期'
                            }
                        }
                    }
                }
            });
        }
        
        // 格式化日期
        function formatDate(dateString) {
            if (!dateString) return '-';
            const date = new Date(dateString);
            return date.toLocaleDateString('zh-CN');
        }
        
        // 格式化数字
        function formatNumber(num) {
            if (num === null || num === undefined) return '-';
            return Number(num).toFixed(2);
        }
        
        // 设置默认日期
        document.addEventListener('DOMContentLoaded', function() {
            const today = new Date();
            const lastWeek = new Date();
            lastWeek.setDate(today.getDate() - 7);
            
            function formatDateInput(date) {
                return date.toISOString().split('T')[0];
            }
            
            document.getElementById('endDate').value = formatDateInput(today);
            document.getElementById('startDate').value = formatDateInput(lastWeek);
        });
    </script>
</body>
</html>